// 验证身份证
export const checkIdCard = {
  // Wi 加权因子 Xi 余数0~10对应的校验码 Pi省份代码
  Wi: [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
  Xi: [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2],
  Pi: [11, 12, 13, 14, 15, 21, 22, 23, 31, 32, 33, 34, 35, 36, 37, 41, 42,
    43, 44, 45, 46, 50, 51, 52, 53, 54, 61, 62, 63, 64, 65, 71, 81, 82,
    91],
  message: '',

  // 检验18位身份证号码出生日期是否有效
  // parseFloat过滤前导零，年份必需大于等于1900且小于等于当前年份，用Date()对象判断日期是否有效。
  brithday18: function (sIdCard: string) {
    const year = parseFloat(sIdCard.substr(6, 4))
    const month = parseFloat(sIdCard.substr(10, 2))
    const day = parseFloat(sIdCard.substr(12, 2))
    const checkDay = new Date(year, month - 1, day)
    const nowDay = new Date()

    if (year >= 1900 && year <= nowDay.getFullYear() &&
                month === (checkDay.getMonth() + 1) &&
                day === checkDay.getDate()) {
      return true
    }

    this.message += '18位身份证号码出生日期格式无效'
  },

  // 检验15位身份证号码出生日期是否有效
  brithday15: function (sIdCard: string) {
    const year = parseFloat(sIdCard.substr(6, 2))
    const month = parseFloat(sIdCard.substr(8, 2))
    const day = parseFloat(sIdCard.substr(10, 2))
    const checkDay = new Date(year, month - 1, day)

    if (month === (checkDay.getMonth() + 1) && day === checkDay.getDate()) {
      return true
    }

    this.message += '15位身份证号码出生日期格式无效'
  },

  // 检验校验码是否有效
  validate: function (sIdCard: string) {
    const aIdCard = sIdCard.split('')
    let sum = 0
    for (let i = 0; i < this.Wi.length; i++) {
      sum += this.Wi[i] * parseInt(aIdCard[i]) // 线性加权求和
    }

    const index = sum % 11// 求模，可能为0~10,可求对应的校验码是否于身份证的校验码匹配
    if (String(this.Xi[index]) === aIdCard[17].toUpperCase()) {
      return true
    }

    this.message += '校验码无效'
  },

  // 检验输入的省份编码是否有效
  province: function (sIdCard: string) {
    const p2 = sIdCard.substr(0, 2)
    for (let i = 0; i < this.Pi.length; i++) {
      if (String(this.Pi[i]) === p2) {
        return true
      }
    }

    this.message += '省份编码无效'
  },

  // 身份证校验
  test: function (sIdCard: string) {
    this.message = ''

    // 去除字符串的前后空格，允许用户不小心输入前后空格
    // const sIdCard = sIdCard.replace(/^\s+|\s+$/g,"");

    // 判断是否全为18或15位数字，最后一位可以是大小写字母X
    if (!(/^\d{17}[\dxX]$|^\d{15}$/).test(sIdCard)) {
      return '身份证号码须为18位或15位数字' // 允许用户输入大小写X代替罗马数字的Ⅹ
    } else if (sIdCard.length === 18) {
      if (this.province(sIdCard) && this.brithday18(sIdCard) &&
                    this.validate(sIdCard)) {
        return ''
      } else {
        return this.message
      }
    } else if (sIdCard.length === 15) {
      if (this.province(sIdCard) && this.brithday15(sIdCard)) {
        return ''
      } else {
        return this.message
      }
    }

    return ''
  }
}
